#pragma once

#include <vector>

#include "ktoken.h"
#include "kcmd.h"

enum ENUM_OBJECT
{
	OBJ_IO,
	OBJ_VAR,
	OBJ_STACK,
	OBJ_TAPE,
	OBJ_CTRL
};

enum ENUM_METHOD
{
	MET_IN, MET_OUT,
	MET_DECL, MET_DEL, MET_SET,
	MET_PUSH, MET_POP, MET_PEEK, MET_SWAP, MET_CLEAR,
	MET_READ, MET_WRITE, MET_NEXT, MET_PREV, MET_MOVE,
	MET_GOTO, MET_CALL, MET_RETURN, MET_END
};

static int funcParamCount[] =
{
	1, /* abs */
	1, /* sqrt */
	1, /* sin */
	1, /* cos */
	1, /* tan */
	1, /* asin */
	1, /* acos */
	1, /* atan */
	1, /* chr */
	1, /* asc */
	1, /* len */
	2, /* left */
	3, /* mid */
	2, /* right */
	3, /* iif */
	1, /* _tape */
	1, /* _stack */
	0, /* _pop */
	0, /* _peek */
};

class Parser
{
private:
	std::vector<Command> cmds;
	std::vector<Token> tokenList;
	k_uint line;
	k_uint index;

public:
	Parser() : cmds(), tokenList() {}

	std::vector<Command> GetCommands() const;
	void Parse(std::vector<Token> toklst);
	void CleanUp();

private:
	void ParseLabel();

	void ParseIO();
	void ParseIO_IN();
	void ParseIO_OUT();

	void ParseVAR();
	void ParseVAR_DECL();
	void ParseVAR_DEL();
	void ParseVAR_SET();

	void ParseSTACK();
	void ParseSTACK_PUSH();
	void ParseSTACK_POP();
	void ParseSTACK_PEEK();
	void ParseSTACK_SWAP();
	void ParseSTACK_CLEAR();

	void ParseTAPE();
	void ParseTAPE_READ();
	void ParseTAPE_WRITE();
	void ParseTAPE_NEXT();
	void ParseTAPE_PREV();
	void ParseTAPE_MOVE();

	void ParseCTRL();
	void ParseCTRL_GOTO();
	void ParseCTRL_CALL();
	void ParseCTRL_RETURN();
	void ParseCTRL_END();

	void ParseExpression(Command& cmd);
	void ParseExpr(std::vector<Token>& tl);
	void ParseRest(std::vector<Token>& tl);
	void ParseArgList(std::vector<Token>& tl);
	void ConvertToRPN(std::vector<Token>& tl, int startIndex);
};
